package edu.whut.mall.portal.service.impl;

import com.github.pagehelper.PageHelper;
import edu.whut.mall.common.api.CommonPage;
import edu.whut.mall.common.exception.MallException;
import edu.whut.mall.mapper.GroupBuyOrderMapper;
import edu.whut.mall.mapper.GroupBuyRuleMapper;
import edu.whut.mall.mapper.ProductMapper;
import edu.whut.mall.mapper.ShippingMapper;
import edu.whut.mall.model.GroupBuyOrder;
import edu.whut.mall.model.GroupBuyRule;
import edu.whut.mall.model.Product;
import edu.whut.mall.model.Shipping;
import edu.whut.mall.portal.domain.PayInfoParams;
import edu.whut.mall.portal.enums.OrderStatusEnum;
import edu.whut.mall.portal.mapper.GroupBuyOrderCustomMapper;
import edu.whut.mall.portal.mapper.ProductCustomMapper;
import edu.whut.mall.portal.service.IGroupBuyOrderService;
import edu.whut.mall.portal.vo.GroupBuyOrderVo;
import edu.whut.mall.portal.vo.GroupBuyRecordVo;
import edu.whut.mall.portal.vo.ProductDetailVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.n3r.idworker.Sid;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
* @program: d9lab-mall
* @description: 团购订单 Service实现
* @author Wayne
* @date 2020-05-21 16:15:55
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class GroupBuyOrderServiceImpl implements IGroupBuyOrderService {


    private final GroupBuyOrderMapper groupBuyOrderMapper;

    private final GroupBuyRuleMapper groupBuyRuleMapper;

    private final ShippingMapper shippingMapper;

    private final ProductCustomMapper productCustomMapper;

    private final GroupBuyOrderCustomMapper groupBuyOrderCustomMapper;

    private final ProductMapper productMapper;




    @Override
    @Transactional
    public GroupBuyOrderVo createGroupBuyOrder(PayInfoParams payInfoParams) throws MallException {
        Shipping shipping = shippingMapper.selectByPrimaryKey(payInfoParams.getShippingId());
        if (shipping == null){
            log.info("地址不存在");
            throw new MallException("收货地址不存在");
        }
        GroupBuyRule rule = groupBuyRuleMapper.selectByPrimaryKey(payInfoParams.getGroupBuyRuleId());
        if (rule == null){
            log.info("团购规则不存在");
            throw new MallException("团购规则不存在");
        }
        //减少库存
        reduceStock(rule.getProductId(), payInfoParams.getQuantity());
        GroupBuyOrder order = buildOrder(payInfoParams, rule, shipping);
        groupBuyOrderMapper.insertSelective(order);
        GroupBuyOrderVo orderVo = transOrder2Vo(order);
        return orderVo;
    }

    @Override
    public CommonPage<GroupBuyRecordVo> getGroupBuyRecordVosByUserIdAndRecordStatusAndUserType(Integer pageNum, Integer size, Long userId, Integer status, Integer userType) {
        PageHelper.startPage(pageNum, size);
        List<GroupBuyRecordVo> groupBuyRecordVos = groupBuyOrderCustomMapper.getGroupBuyRecordVosByUserIdAndRecordStatusAndUserType(userId, status, userType);
        return CommonPage.restPage(groupBuyRecordVos);
    }

    @Override
    public CommonPage<GroupBuyRecordVo> getGroupBuyRecordProcessingVos(Integer pageNum, Integer size, Long ruleId, Integer status) {
        PageHelper.startPage(pageNum, size);
        List<GroupBuyRecordVo> groupBuyRecordVos = groupBuyOrderCustomMapper.getGroupBuyRecordVosByRuleIdAndStatus(ruleId, status);
        return CommonPage.restPage(groupBuyRecordVos);
    }

    @Override
    public GroupBuyOrderVo getGroupBuyOrderVoByRecordIdAndUserId(Long recordId, Long userId) {
        return groupBuyOrderCustomMapper.getGroupBuyOrderVoByRecordIdAndUserId(recordId, userId);
    }

    @Override
    public CommonPage<GroupBuyOrderVo> getGroupBuyOrderVoByOrderStatus(Integer pageNum, Integer size, Long userId, Integer orderStatus) {
        PageHelper.startPage(pageNum, size);
        List<GroupBuyOrderVo> groupBuyOrderVos =groupBuyOrderCustomMapper.getGroupBuyOrderVoByOrderStatus(userId, orderStatus);
        return  CommonPage.restPage(groupBuyOrderVos);
    }

    @Override
    public GroupBuyOrderVo getGroupBuyOrderVoByOrderNo(String orderNo) {
       return groupBuyOrderCustomMapper.getGroupBuyOrderVoByOrderNo(orderNo);
    }

    @Override
    public Integer confirmReceipt(String orderNo) {
        return groupBuyOrderCustomMapper.confirmReceipt(orderNo);
    }

    @Override
    public Integer deleteOrder(String orderNo) {
        return groupBuyOrderCustomMapper.deleteOrder(orderNo);
    }


    /**
     * 组建订单
     * @param payInfoParams
     * @param groupBuyRule
     * @return
     */
    private GroupBuyOrder buildOrder(PayInfoParams payInfoParams, GroupBuyRule groupBuyRule, Shipping shipping){
        GroupBuyOrder order = new GroupBuyOrder();
        order.setOrderNo(generatorOrderNo());
        order.setUserId(payInfoParams.getUserId());
        order.setReceiveAddress(shipping.getReceiveAddress());
        order.setPhone(shipping.getReceivePhone());
        order.setUserName(shipping.getReceiveName());
        order.setProductId(groupBuyRule.getProductId());
        order.setQuantity(payInfoParams.getQuantity());
        order.setTotalMoney(groupBuyRule.getGroupBuyPrice());
        order.setOrderStatus(OrderStatusEnum.NO_PAY.getCode());
        order.setPostage(BigDecimal.valueOf(0));
        return order;
    }

    /**
     * 转换成展示层
     * @param order
     * @return
     */
    private GroupBuyOrderVo transOrder2Vo(GroupBuyOrder order){
        GroupBuyOrderVo orderVo = new GroupBuyOrderVo();
        BeanUtils.copyProperties(order, orderVo);
        ProductDetailVo productDetailVo = productCustomMapper.getProductDetailVoByProductId(order.getProductId());
        orderVo.setProductDetailVo(productDetailVo);
        return orderVo;
    }


    /**
     * 生成订单号
     * @return
     */
    private String generatorOrderNo(){
        return "t"+ Sid.nextShort();
    }

    /**
     * 减少库存
     * @param productId
     * @param amount
     */
    private void reduceStock(Long productId, Integer amount){
        Product product = productMapper.selectByPrimaryKey(productId);
        if (product.getStock() <= 0) {
            throw new MallException("库存不足");
        }
        else {
            product.setStock(product.getStock() - amount);
            product.setSell(product.getSell() + amount);
            productMapper.updateByPrimaryKeySelective(product);
        }

    }
}



